package org.ecpkn.PAGridSim.core.offlineOptimization.workloadBalance;

import java.util.ArrayList;
import java.util.Collections;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.ecpkn.PAGridSim.core.PAEntityFactory;
import org.ecpkn.PAGridSim.core.configuration.Configuration;
import org.ecpkn.PAGridSim.core.configuration.Configuration.Const;
import org.ecpkn.PAGridSim.core.gridsimEntity.paMachine.ComparatorMachineUtilization;
import org.ecpkn.PAGridSim.core.gridsimEntity.paMachine.PAMachine;
import org.ecpkn.PAGridSim.core.tasksCreation.Task;

public class LoadBalanceStrategy {
	
	private static final Logger logger = LogManager
			.getLogger(LoadBalanceStrategy.class);
	// Strategy by default:LargestTaskFirst
	public static ArrayList<PAMachine> schedule(double timePoint,
			int machineNumber,int frequency, ArrayList<Task> tasks) throws Exception {
		ComparatorTaskUtilization comparator = new ComparatorTaskUtilization();
		Collections.sort(tasks, comparator);
		ArrayList<PAMachine> ml = new ArrayList<PAMachine>();
		for (int index = 0; index < machineNumber; index++) {
			// TODO:stocked value in configuration,not get every time
			PAMachine m = PAEntityFactory.createCustomizedMachine(
					Configuration.getInstance().getParameterString(
							Const.SIMULATION_MACHINE), index, 1,
							frequency);
			ml.add(m);
		}
		ComparatorMachineUtilization c = new ComparatorMachineUtilization();
		for (Task t : tasks) {
			if (t.getSubmitedTime_() <= timePoint && t.getEndTime() > timePoint) {
				PAMachine m = Collections.min(ml, c);
				m.addTaskToMachine(t);
				// the utilization is only used for comparison among tasks, the
				// real utilization of a machine with a task set is calculated
				// in PAPolicy in run time
				m.changeSingleTaskMachineUtilization(t
						.getUtilization(frequency));
				//TODO:UPDATE with a task,not a utilization
				//TODO:it seems there are problem with real utilization
			}
		}
		return ml;
	}
}
